---
type: tutorial
title: Создайте архив записей блога
description: |-
  Руководство: Создайте свой первый блог на Astro —
  Используйте import.meta.glob(), чтобы получить доступ к данным из файлов в вашем проекте
i18nReady: true
---
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

Теперь, когда у вас есть несколько блогов для ссылок, давайте настроим страницу блога для автоматического создания списка из них!

<PreCheck>
  - Получить доступ к данным из всех ваших записей сразу, используя `import.meta.glob()`
  - Отобразить динамически генерируемый список записей на странице «Блог»
  - Провести рефакторинг с использованием компонента `<BlogPost />` для каждого элемента списка
</PreCheck>

## Динамически отобразите список сообщений

<Steps>
1. Добавьте следующий код в `blog.astro` для получения информации обо всех ваших файлах Markdown. `import.meta.glob()` вернет массив объектов, по одному для каждого поста блога.

    ```astro title="src/pages/blog.astro" ins={3}
    ---
    import BaseLayout from '../layouts/BaseLayout.astro'
    const allPosts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
    const pageTitle = "Мой блог об изучении Astro"
    ---
    <BaseLayout pageTitle={pageTitle}>
      <p>Здесь я буду публиковать записи о своем пути изучения Astro.</p>
      <ul>
        <li><a href="/posts/post-1/">Пост 1</a></li>
        <li><a href="/posts/post-2/">Пост 2</a></li>
        <li><a href="/posts/post-3/">Пост 3</a></li>
      </ul>
    </BaseLayout>
    ```


2. Чтобы генерировать весь список сообщений динамически, используя заголовки и URL-адреса сообщений, замените свои отдельные теги `<li>` следующим кодом Astro:

    ```astro title="src/pages/blog.astro" del={9,10,11} ins={13}
    ---
    import BaseLayout from '../layouts/BaseLayout.astro'
    const allPosts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
    const pageTitle = "Мой блог об изучении Astro"
    ---
    <BaseLayout pageTitle={pageTitle}>
      <p>Здесь я буду публиковать записи о своем пути изучения Astro.</p>
      <ul>
        <li><a href="/posts/post-1/">Пост 1</a></li>
        <li><a href="/posts/post-2/">Пост 2</a></li>
        <li><a href="/posts/post-3/">Пост 3</a></li>

        {allPosts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
      </ul>
    </BaseLayout>
    ```

    Теперь весь ваш список блогов генерируется динамически, путём отображение массива, возвращаемого `import.meta.glob()`.

3. Добавьте новую запись в блог, создав новый файл `post-4.md` в `src/pages/posts/` и добавив немного контента Markdown. Обязательно включите метаданные, использованные ниже.

    ```markdown
    ---
    layout: ../../layouts/MarkdownPostLayout.astro
    title: Моя четвёртая запись в блоге
    author: Ученик Astro
    description: "Этот пост появится сам по себе!"
    image:
      url: "https://docs.astro.build/default-og-image.png"
      alt: "Слово «astro» на фоне иллюстрации планет и звезд."
    pubDate: 2022-08-08
    tags: ["astro", "успехи"]
    ---
    Этот пост должен отображаться вместе с другими моими записями в блоге, потому что `import.meta.glob()` возвращает список всех моих постов для создания списка.
    ```

4. Посетите страницу вашего блога в предварительном просмотре браузера по адресу `http://localhost:4321/blog` и поищите обновлённый список из четырёх элементов, включая вашу новую запись!
</Steps>

<Box icon="puzzle-piece">

## Задача: Создать компонент BlogPost

Попробуйте самостоятельно внести все необходимые изменения в проект Astro, чтобы можно было использовать следующий код для генерации списка записей блога:

```astro title="src/pages/blog.astro" del={2} ins={3}
<ul>
  {allPosts.map((post: any) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
  {allPosts.map((post: any) => <BlogPost url={post.url} title={post.frontmatter.title} />)}
</ul>
```

<details>
<summary>Развернуть, чтобы увидеть шаги</summary>

<Steps>
1. Создайте новый компонент в `src/components/`.

    <details>
    <summary>Показать имя файла</summary>
    ```
    BlogPost.astro
    ```
    </details>

2. Напишите строку кода в вашем компоненте, чтобы он мог принимать `title` и `url` в качестве `Astro.props`.

    <details>
    <summary>Показать код</summary>
    ```astro
    ---
    // src/components/BlogPost.astro
    const { title, url } = Astro.props;
    ---
    ```
    </details>

3. Добавьте шаблонизацию, используемую для создания каждого элемента в списке записей блога.

    <details>
    <summary>Показать код</summary>
    ```astro
    <!-- src/components/BlogPost.astro -->
    <li><a href={url}>{title}</a></li>
    ```
    </details>

4. Импортируйте новый компонент на страницу «Блог».

    <details>
    <summary>Показать код</summary>
    ```astro title="src/pages/blog.astro" ins={3}
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    import BlogPost from '../components/BlogPost.astro';
    const allPosts = Object.values(import.meta.glob('../pages/posts/*.md', { eager: true }));
    const pageTitle = "Мой блог об изучении Astro";
    ---
    ```
    </details>

5. Проверьте себя: посмотрите окончательный код компонента.

    <details>
    <summary>Показать код</summary>
    ```astro title="src/components/BlogPost.astro"
    ---
    const { title, url } = Astro.props
    ---
    <li><a href={url}>{title}</a></li>
    ```
    ```astro title="src/pages/blog.astro" ins={3,10}
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    import BlogPost from '../components/BlogPost.astro';
    const allPosts = Object.values(import.meta.glob('../pages/posts/*.md', { eager: true }));
    const pageTitle = "Мой блог об изучении Astro"
    ---
    <BaseLayout pageTitle={pageTitle}>
      <p>Здесь я буду публиковать записи о своем пути изучения Astro.</p>
      <ul>
        {allPosts.map((post: any) => <BlogPost url={post.url} title={post.frontmatter.title} />)}
      </ul>
    </BaseLayout>
    ```
    </details>
</Steps>
</details>
</Box>



<Box icon="question-mark">

### Проверьте свои знания

Если ваш компонент Astro содержит следующую строку кода:

```astro
---
const myPosts = Object.values(import.meta.glob('./posts/*.md', { eager:  true }));
---
```

Выберите синтаксис, который вы могли бы написать для представления:

1. Заголовка вашей третьей записи в блоге.

    <MultipleChoice>
      <Option>
        `myPosts.map((post) => <LastUpdated date={post.frontmatter.pubDate} />)`
      </Option>
      <Option isCorrect>
        `myPosts[2].frontmatter.title`
      </Option>
      <Option>
        `<a href={myPosts[0].url}>Первый пост!!</a>`
      </Option>
    </MultipleChoice>

2. Ссылки на URL вашей первой записи в блоге.

    <MultipleChoice>
      <Option>
        `myPosts.map((post) => <LastUpdated date={post.frontmatter.pubDate} />)`
      </Option>
      <Option>
        `myPosts[2].frontmatter.title`
      </Option>
      <Option isCorrect>
        `<a href={myPosts[0].url}>Первый пост!!</a>`
      </Option>
    </MultipleChoice>

3. Компонента для каждого поста, отображающего дату его последнего обновления.

    <MultipleChoice>
      <Option isCorrect>
        `myPosts.map((post) => <LastUpdated date={post.frontmatter.pubDate} />)`
      </Option>
      <Option>
        `myPosts[2].frontmatter.title`
      </Option>
      <Option>
        `<a href={myPosts[0].url}>Первый пост!!</a>`
      </Option>
    </MultipleChoice>

</Box>

## Контрольный список

<Box icon="check-list">

<Checklist>
- [ ] Я умею запрашивать данные из моих локальных файлов.
- [ ] Я умею отображать список всех моих записей блога.
</Checklist>
</Box>

### Ресурсы

- [Импорт шаблонов glob в Astro](/ru/guides/imports/#importmetaglob)
